/*******************************************************************************
 *                                    ZLG
 *                         ----------------------------
 *                         innovating embedded platform
 *
 * Copyright (c) 2001-present Guangzhou ZHIYUAN Electronics Co., Ltd.
 * All rights reserved.
 *
 * Contact information:
 * web site:    https://www.zlg.cn
 *******************************************************************************/
#ifndef __HPM6E00_L1_CACHE_H
#define __HPM6E00_L1_CACHE_H

#ifdef __cplusplus
extern "C" {
#endif  /* __cplusplus*/
#include "common/hpm_common.h"
#include "riscv/riscv_core.h"
#include "core/include/hpm6e00_regs_csr.h"
#include <stdint.h>

#define HPM_L1C_CACHELINE_SIZE (64)

/* \brief mcache_ctl 寄存器位定义 */

#define HPM_MCACHE_CTL_DC_WAROUND_POS   (13UL)
#define HPM_MCACHE_CTL_DC_WAROUND_MASK  (0x3UL << HPM_MCACHE_CTL_DC_WAROUND_POS)
#define HPM_MCACHE_CTL_DC_WAROUND(x)    (uint32_t)(((x) << HPM_MCACHE_CTL_DC_WAROUND_POS) & HPM_MCACHE_CTL_DC_WAROUND_MASK)

#define HPM_MCACHE_CTL_DPREF_EN_POS     (10UL)
#define HPM_MCACHE_CTL_DPREF_EN_MASK    (0x1UL << HPM_MCACHE_CTL_DPREF_EN_POS)
#define HPM_MCACHE_CTL_DPREF_EN(x)      (uint32_t)(((x) << HPM_MCACHE_CTL_DPREF_EN_POS) & HPM_MCACHE_CTL_DPREF_EN_MASK)

#define HPM_MCACHE_CTL_IPREF_EN_POS     (9UL)
#define HPM_MCACHE_CTL_IPREF_EN_MASK    (0x1UL << HPM_MCACHE_CTL_IPREF_EN_POS)
#define HPM_MCACHE_CTL_IPREF_EN(x)      (uint32_t)(((x) << HPM_MCACHE_CTL_IPREF_EN_POS) & HPM_MCACHE_CTL_IPREF_EN_MASK)

/* \brief Superuser 模式与 User 模式下访问 ucctlbeginaddr 和 ucctlcommand CSRs 使能位 */
#define HPM_MCACHE_CTL_CCTL_SUEN_POS    (8UL)
#define HPM_MCACHE_CTL_CCTL_SUEN_MASK   (0x1UL << HPM_MCACHE_CTL_CCTL_SUEN_POS)
#define HPM_MCACHE_CTL_CCTL_SUEN(x)     (uint32_t)(((x) << HPM_MCACHE_CTL_CCTL_SUEN_POS) & HPM_MCACHE_CTL_CCTL_SUEN_MASK)

/* \brief mcache_ctl 寄存器 D-Cache 使能位 */
#define HPM_MCACHE_CTL_DC_EN_POS        (1UL)
#define HPM_MCACHE_CTL_DC_EN_MASK       (1UL << HPM_MCACHE_CTL_DC_EN_POS)
#define HPM_MCACHE_CTL_DC_EN(x)         (uint32_t)(((x) << HPM_MCACHE_CTL_DC_EN_POS) & HPM_MCACHE_CTL_DC_EN_MASK)

/* \brief mcache_ctl 寄存器 I-Cache 使能位 */
#define HPM_MCACHE_CTL_IC_EN_POS        (0UL)
#define HPM_MCACHE_CTL_IC_EN_MASK       (1UL << HPM_MCACHE_CTL_IC_EN_POS)
#define HPM_MCACHE_CTL_IC_EN(x)         (uint32_t)(((x) << HPM_MCACHE_CTL_IC_EN_POS) & HPM_MCACHE_CTL_IC_EN_MASK)

#define HPM_L1C_CCTL_CMD_L1D_VA_INVAL       (0UL)
#define HPM_L1C_CCTL_CMD_L1D_WBINVAL_ALL    (6UL)
#define HPM_L1C_CCTL_CMD_L1D_INVAL_ALL      (23UL)

/**
 * \brief 获取控制寄存器值
 */
__attribute__((always_inline)) static inline uint32_t l1c_get_control(void){
    return read_csr(CSR_MCACHE_CTL);
}

/**
 * \brief l1 cache D-Cache 是否使能
 */
__attribute__((always_inline)) static inline int l1c_dc_is_enabled(void){
    return l1c_get_control() & HPM_MCACHE_CTL_DC_EN_MASK;
}

/**
 * \brief l1 cache I-Cache 是否使能
 */
__attribute__((always_inline)) static inline int l1c_ic_is_enabled(void){
    return l1c_get_control() & HPM_MCACHE_CTL_IC_EN_MASK;
}

/**
 * \brief 发送命令
 */
__attribute__((always_inline)) static inline void l1c_cctl_cmd(uint8_t cmd){
    write_csr(CSR_MCCTLCOMMAND, cmd);
}

__attribute__((always_inline)) static inline void l1c_cctl_address(uint32_t address){
    write_csr(CSR_MCCTLBEGINADDR, address);
}

__attribute__((always_inline)) static inline uint32_t l1c_cctl_get_address(void){
    return read_csr(CSR_MCCTLBEGINADDR);
}

/**
 * \brief l1 cache D-Cache 使能
 */
void l1c_dc_enable(void);
/**
 * \brief l1 cache D-Cache 禁能
 */
void l1c_dc_disable(void);
/**
 * \brief l1 cache I-Cache 使能
 */
void l1c_ic_enable(void);
/**
 * \brief l1 cache I-Cache 禁能
 */
void l1c_ic_disable(void);
/**
 * \brief l1 cache 无效化
 */
void l1c_dc_invalidate(uint32_t address, uint32_t size);
/**
 * \brief l1 cache 无效化全部 D-Cache
 */
void l1c_dc_invalidate_all(void);
/**
 * \brief l1 cache 刷新全部 D-Cache
 */
void l1c_dc_flush_all(void);
/**
 * \brief l1 cache D-Cache writearound 使能
 */
void l1c_dc_enable_writearound(void);
#ifdef __cplusplus
}
#endif  /* __cplusplus  */

#endif

